home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / 3d_tools / irit40s.lha / Irit / grapdrvs / xgladap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-30  |  36.6 KB  |  1,237 lines

  1. /*****************************************************************************
  2. *   An SGI 4D driver using GL (experimental adaptive isocurve renderer.).    *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.1, June 1993.  *
  5. *****************************************************************************/
  6.  
  7. #include <gl/gl.h>
  8. #include <gl/device.h>
  9.  
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <math.h>
  13. #include <ctype.h>
  14. #include "irit_sm.h"
  15. #include "genmat.h"
  16. #include "config.h"
  17. #include "iritprsr.h"
  18. #include "allocate.h"
  19. #include "attribut.h"
  20. #include "ip_cnvrt.h"
  21. #include "cagd_lib.h"
  22. #include "iritgrap.h"
  23. #include "irit_soc.h"
  24.  
  25. /* Interactive menu setup structure: */
  26. #define INTERACT_NUM_OF_STRINGS        4
  27. #define INTERACT_NUM_OF_SUB_WNDWS    16
  28.  
  29. typedef struct InteractString {
  30.     RealType X, Y;
  31.     int Color;
  32.     char *Str;
  33. } InteractString;
  34. typedef struct InteractSubWindow {
  35.     RealType X, Y;                       /* Center points. */
  36.     int Color;
  37.     IGGraphicEventType Event;
  38.     int TextInside; /* If TRUE, Str will be in window, otherwise left to it. */
  39.     char *Str;
  40. } InteractSubWindow;
  41. typedef struct InteractWindowStruct {     /* The interactive menu structures. */
  42.     /* Rotate, Translate, Scale strings: */
  43.     InteractString Strings[INTERACT_NUM_OF_STRINGS];
  44.     InteractSubWindow SubWindows[INTERACT_NUM_OF_SUB_WNDWS];
  45. } InteractWindowStruct;
  46.  
  47. #define INTERACT_SUB_WINDOW_WIDTH  0.8         /* Relative to window size. */
  48. #define INTERACT_SUB_WINDOW_HEIGHT 0.04
  49.  
  50. static int
  51.     GlblStateMenu = 0,
  52.     GlblRuledSrfApprox = FALSE;
  53.  
  54. static long
  55.     TransWinID = 0,
  56.     TransWinWidth = 100,
  57.     TransWinWidth2 = 50,
  58.     TransWinHeight = 100,
  59.     TransWinLow = 0,
  60.     TransWinLeft = 0,
  61.     ViewWinID = 0,
  62.     ViewWinWidth = 100,
  63.     ViewWinWidth2 = 50,
  64.     ViewWinHeight = 100,
  65.     ViewWinHeight2 = 50,
  66.     ViewWinLow = 0,
  67.     ViewWinLeft = 0;
  68.  
  69. static RealType
  70.     GlblAdapIsoEps = 0.05,
  71.     GlblRuledSrfEps = 0.02;
  72.  
  73. /* Interactive mode menu set up structure is define below: */
  74. static InteractWindowStruct InteractMenu = {
  75.     { { 0.5, 0.81, IG_IRIT_RED,        "Rotate" },
  76.       { 0.5, 0.65, IG_IRIT_GREEN,    "Translate" },
  77.       { 0.5, 0.49, IG_IRIT_CYAN,    "Scale" },
  78.       { 0.5, 0.41, IG_IRIT_LIGHTGREEN,    "Clip Plane" },
  79.     },
  80.     { { 0.5, 0.93, IG_IRIT_YELLOW, IG_EVENT_SCR_OBJ_TGL,    TRUE,  "Screen Coords." },
  81.       { 0.5, 0.87, IG_IRIT_BLUE,   IG_EVENT_PERS_ORTHO_TGL,     TRUE,  "Perspective" },
  82.       { 0.5, 0.83, IG_IRIT_BLUE,   IG_EVENT_PERS_ORTHO_Z,    FALSE, "Z" },
  83.       { 0.5, 0.75, IG_IRIT_RED,    IG_EVENT_ROTATE_X,        FALSE, "X" }, /* Rot */
  84.       { 0.5, 0.71, IG_IRIT_RED,    IG_EVENT_ROTATE_Y,        FALSE, "Y" },
  85.       { 0.5, 0.67, IG_IRIT_RED,    IG_EVENT_ROTATE_Z,        FALSE, "Z" },
  86.       { 0.5, 0.59, IG_IRIT_GREEN,  IG_EVENT_TRANSLATE_X,    FALSE, "X" }, /* Trans */
  87.       { 0.5, 0.55, IG_IRIT_GREEN,  IG_EVENT_TRANSLATE_Y,    FALSE, "Y" },
  88.       { 0.5, 0.51, IG_IRIT_GREEN,  IG_EVENT_TRANSLATE_Z,    FALSE, "Z" },
  89.       { 0.5, 0.43, IG_IRIT_CYAN,   IG_EVENT_SCALE,        FALSE, "" },  /* Scale */
  90.       { 0.5, 0.35, IG_IRIT_LIGHTGREEN, IG_EVENT_NEAR_CLIP,    FALSE,  "" },
  91.       { 0.5, 0.31, IG_IRIT_LIGHTGREEN, IG_EVENT_FAR_CLIP,    FALSE,  "" },
  92.  
  93.       { 0.5, 0.20, IG_IRIT_YELLOW, IG_EVENT_SAVE_MATRIX,    TRUE,  "Save Matrix" },
  94.       { 0.5, 0.13, IG_IRIT_YELLOW, IG_EVENT_PUSH_MATRIX,    TRUE,  "Push Matrix" },
  95.       { 0.5, 0.09, IG_IRIT_YELLOW, IG_EVENT_POP_MATRIX,        TRUE,  "Pop Matrix" },
  96.       { 0.5, 0.03, IG_IRIT_WHITE,  IG_EVENT_QUIT,        TRUE,  "Quit" },
  97.     }
  98. };
  99.  
  100. static short Colors[IG_MAX_COLOR + 1][3] =
  101. {
  102.     { 0,   0,   0   },  /* 0. BLACK */
  103.     { 0,   0,   170 },  /* 1. BLUE */
  104.     { 0,   170, 0   },  /* 2. GREEN */
  105.     { 0,   170, 170 },  /* 3. CYAN */
  106.     { 170, 0,   0   },  /* 4. RED */
  107.     { 170, 0,   170 },  /* 5. MAGENTA */
  108.     { 170, 170, 0   },  /* 6. BROWN */
  109.     { 170, 170, 170 },  /* 7. LIGHTGREY */
  110.     { 85,  85,  85  },  /* 8. DARKGRAY */
  111.     { 85,  85,  255 },  /* 9. LIGHTBLUE */
  112.     { 85,  255, 85  },  /* 10. LIGHTGREEN */
  113.     { 85,  255, 255 },  /* 11. LIGHTCYAN */
  114.     { 255, 85,  85  },  /* 12. LIGHTRED */
  115.     { 255, 85,  255 },  /* 13. LIGHTMAGENTA */
  116.     { 255, 255, 85  },  /* 14. YELLOW */
  117.     { 255, 255, 255 }   /* 15. WHITE */
  118. };
  119.  
  120. static void IGDrawPolyNormal(IPObjectStruct *PObj, int HasNormals);
  121. static IPPolygonStruct *IritSurface2AdapIso(CagdSrfStruct *Srf,
  122.                         CagdSrfDirType Dir,
  123.                         RealType Eps, int SamplesPerCurve);
  124. static void SetColorIndex(int c);
  125. static void SetColorRGB(int Color[3]);
  126. static void ClearViewArea(void);
  127. static void SetTransformWindow(void);
  128. static void RedrawTransformWindow(void);
  129. static void SetViewWindow(void);
  130. static void RedrawViewWindow(void);
  131. static int IsAbortKeyPressed(void);
  132. static void ProcessEvent(IGGraphicEventType Event, RealType ChangeFactor);
  133. static IGGraphicEventType GetGraphicEvent(RealType *ChangeFactor);
  134. static void DrawText(char *Str, long PosX, long PosY);
  135.  
  136. /****************************************************************************
  137. * Pop up all windows, read input and display.                    *
  138. ****************************************************************************/
  139. void main(int argc, char **argv)
  140. {
  141.     RealType ChangeFactor;
  142.     IGGraphicEventType Event;
  143.     IPObjectStruct *PObjects;
  144.  
  145.     IGConfigureGlobals("xgladap", argc, argv);
  146.  
  147.     SetViewWindow();
  148.     RedrawViewWindow();
  149.     SetTransformWindow();
  150.     RedrawTransformWindow();
  151.  
  152.     qdevice(LEFTMOUSE);
  153.     qdevice(MIDDLEMOUSE);
  154.     qdevice(RIGHTMOUSE);
  155.  
  156.     /* The default drawing window is the view window. */
  157.     winset(ViewWinID);
  158.  
  159.     setbell(1);                           /* Make it short. */
  160.  
  161.     IGCreateStateMenu();
  162.  
  163.     if (!IGGlblStandAlone)
  164.     SocClientCreateSocket();
  165.  
  166.     while ((Event = GetGraphicEvent(&ChangeFactor)) != IG_EVENT_QUIT) {
  167.     if (IGProcessEvent(Event, ChangeFactor * IGGlblChangeFactor))
  168.         RedrawViewWindow();
  169.     }
  170.  
  171.     if (!IGGlblStandAlone)
  172.     SocClientCloseSocket();
  173. }
  174.  
  175. /*****************************************************************************
  176. * Construct global pop up menu.                             *
  177. *****************************************************************************/
  178. void IGCreateStateMenu(void)
  179. {
  180.     if (GlblStateMenu) 
  181.         freepup(GlblStateMenu);
  182.  
  183.     GlblStateMenu = newpup();
  184.  
  185.     addtopup(GlblStateMenu, " Set Up %t", 0);
  186.     addtopup(GlblStateMenu, "Oops!%l", 0);
  187.     addtopup(GlblStateMenu, "More Sensitive", 0);
  188.     addtopup(GlblStateMenu, "Less Sensitive%l", 0);
  189.     addtopup(GlblStateMenu, IGGlblTransformMode == IG_TRANS_SCREEN ?
  190.                 "Screen Trans." : "Object Trans", 0);
  191.     addtopup(GlblStateMenu, IGGlblViewMode == IG_VIEW_PERSPECTIVE ?
  192.                 "Perspective" : "Orthographic", 0);
  193.     addtopup(GlblStateMenu,
  194.          IGGlblDepthCue ? "Depth Cue" : "No Depth Cue", 0);
  195.     addtopup(GlblStateMenu,
  196.          IGGlblDrawSolid ? "Draw Solid" : "Draw Wireframe", 0);
  197.     addtopup(GlblStateMenu,
  198.          IGGlblDoDoubleBuffer ? "Double Buffer" : "Single Buffer", 0);
  199.     addtopup(GlblStateMenu,
  200.          IGGlblAntiAliasing ? "Anti Aliasing" : "No Anti Aliasing", 0);
  201.     addtopup(GlblStateMenu,
  202.          IGGlblDrawInternal ? "Draw Internal Edges" : "No Internal Edges", 0);
  203.     addtopup(GlblStateMenu,
  204.          IGGlblDrawVNormal ? "Draw Vrtx Normals" :  "No Vrtx Normals", 0);
  205.     addtopup(GlblStateMenu,
  206.          IGGlblDrawPNormal ? "Draw Poly Normals" :  "No Poly Normals", 0);
  207.     addtopup(GlblStateMenu,
  208.          IGGlblDrawSurfaceMesh ? "Draw Surface Mesh" : "No Surface Mesh", 0);
  209.     addtopup(GlblStateMenu,
  210.          IGGlblDrawSurfacePoly ? "Surface Polygons" : "Surface Isolines", 0);
  211.     addtopup(GlblStateMenu,
  212.          IGGlblFourPerFlat ? "Four Per Flat%l" : "Two Per Flat%l", 0);
  213.     addtopup(GlblStateMenu, "More Isolines", 0);
  214.     addtopup(GlblStateMenu, "Less Isolines%l", 0);
  215.     addtopup(GlblStateMenu, "Finer Approx.", 0);
  216.     addtopup(GlblStateMenu, "Coarser Approx.%l", 0);
  217.     addtopup(GlblStateMenu, "Longer Vectors.", 0);
  218.     addtopup(GlblStateMenu, "Shorter Vectors%l", 0);
  219.     addtopup(GlblStateMenu, "Thicker Lines.", 0);
  220.     addtopup(GlblStateMenu, "Thinner Lines%l", 0);
  221.     addtopup(GlblStateMenu, "Finer Adap. Iso.", 0);
  222.     addtopup(GlblStateMenu, "Coarser Adap. Iso.", 0);
  223.     addtopup(GlblStateMenu, "Finer Ruled Srf.", 0);
  224.     addtopup(GlblStateMenu, "Coarser Ruled Srf.", 0);
  225.     addtopup(GlblStateMenu, 
  226.          GlblRuledSrfApprox ? "Direct Adap. Iso." : "Ruled Adap. Iso.", 0);
  227.     addtopup(GlblStateMenu, "Adap. Iso. Dir.", 0);
  228. }
  229.  
  230. /****************************************************************************
  231. * Draw a Point/Vector object using current modes and transformations.        *
  232. ****************************************************************************/
  233. void IGDrawPtVec(IPObjectStruct *PObj)
  234. {
  235.     static PointType
  236.     Zero = { 0.0, 0.0, 0.0 };
  237.     int i;
  238.     PointType Ends[6];
  239.     RealType
  240.     *Pt = PObj -> U.Pt;
  241.  
  242.     IGSetColorObj(PObj);
  243.  
  244.     for (i = 0; i < 6; i++)
  245.     PT_COPY(Ends[i], Pt);
  246.  
  247.     Ends[0][0] -= IG_POINT_WIDTH;
  248.     Ends[1][0] += IG_POINT_WIDTH;
  249.     Ends[2][1] -= IG_POINT_WIDTH;
  250.     Ends[3][1] += IG_POINT_WIDTH;
  251.     Ends[4][2] -= IG_POINT_WIDTH;
  252.     Ends[5][2] += IG_POINT_WIDTH;
  253.  
  254.     for (i = 0; i < 6; i += 2) {
  255.     bgnline();
  256.     v3d(Ends[i]);
  257.     v3d(Ends[i+1]);
  258.     endline();
  259.     }
  260.  
  261.     if (IP_IS_VEC_OBJ(PObj)) {
  262.     bgnline();
  263.     v3d(Pt);
  264.     v3d(Zero);
  265.     endline();
  266.     }
  267. }
  268.  
  269. /****************************************************************************
  270. * Draw a Poly object using current modes and transformations.            *
  271. ****************************************************************************/
  272. void IGDrawPoly(IPObjectStruct *PObj)
  273. {
  274.     IGDrawPolyNormal(PObj, FALSE);
  275. }
  276.  
  277. /****************************************************************************
  278. * Draw a Poly object using current modes and transformations.            *
  279. *   This function allowes polylines to have normals so we can actually draw *
  280. * the adaptive isolines to render a surface.                    *
  281. ****************************************************************************/
  282. static void IGDrawPolyNormal(IPObjectStruct *PObj, int HasNormals)
  283. {
  284.     IPVertexStruct *V;
  285.     IPPolygonStruct
  286.     *Pl = PObj -> U.Pl;
  287.  
  288.     IGSetColorObj(PObj);
  289.  
  290.     if (IP_IS_POLYLINE_OBJ(PObj)) {
  291.     for (; Pl != NULL; Pl = Pl -> Pnext) {
  292.         bgnline();
  293.         for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
  294.         if (HasNormals) {
  295.             float n[3];
  296.  
  297.             n[0] = V -> Normal[0];
  298.             n[1] = V -> Normal[1];
  299.             n[2] = V -> Normal[2];
  300.             n3f(n);
  301.         }
  302.             v3d(V -> Coord);
  303.         }
  304.         endline();
  305.     }
  306.     }
  307.     else if (IP_IS_POINTLIST_OBJ(PObj)) {
  308.     for (; Pl != NULL; Pl = Pl -> Pnext) {
  309.         for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
  310.         int i;
  311.         PointType Ends[6];
  312.         RealType
  313.             *Pt = V -> Coord;
  314.  
  315.         for (i = 0; i < 6; i++)
  316.             PT_COPY(Ends[i], Pt);
  317.  
  318.         Ends[0][0] -= IG_POINT_WIDTH;
  319.         Ends[1][0] += IG_POINT_WIDTH;
  320.         Ends[2][1] -= IG_POINT_WIDTH;
  321.         Ends[3][1] += IG_POINT_WIDTH;
  322.         Ends[4][2] -= IG_POINT_WIDTH;
  323.         Ends[5][2] += IG_POINT_WIDTH;
  324.  
  325.         for (i = 0; i < 6; i += 2) {
  326.             bgnline();
  327.             v3d(Ends[i]);
  328.             v3d(Ends[i+1]);
  329.             endline();
  330.         }
  331.         }
  332.     }
  333.     }
  334.     else if (IP_IS_POLYGON_OBJ(PObj)) {
  335.     int i, j,
  336.         NumOfVertices;
  337.     PointType PNormal, VNormal;
  338.  
  339.     for (; Pl != NULL; Pl = Pl -> Pnext) {
  340.         if (IGGlblDrawPNormal) {
  341.         NumOfVertices = 0;
  342.         PNormal[0] = PNormal[1] = PNormal[2] = 0.0;
  343.         }
  344.  
  345.         if (IGGlblDrawSolid) {
  346.         bgnpolygon();
  347.         for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
  348.             float n[3];
  349.  
  350.             n[0] = V -> Normal[0];
  351.             n[1] = V -> Normal[1];
  352.             n[2] = V -> Normal[2];
  353.             n3f(n);
  354.             v3d(V -> Coord);
  355.  
  356.             if (IGGlblDrawPNormal) {
  357.             for (j = 0; j < 3; j++)
  358.                 PNormal[j] += V -> Coord[j];
  359.             NumOfVertices++;
  360.             }
  361.         }
  362.         endpolygon();
  363.         }
  364.         else {
  365.         bgnline();
  366.         for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
  367.             v3d(V -> Coord);
  368.             if (IP_IS_INTERNAL_VRTX(V) && !IGGlblDrawInternal) {
  369.             endline();
  370.             bgnline();
  371.             }
  372.  
  373.             if (IGGlblDrawPNormal) {
  374.             for (j = 0; j < 3; j++)
  375.                 PNormal[j] += V -> Coord[j];
  376.             NumOfVertices++;
  377.             }
  378.         }
  379.         v3d(Pl -> PVertex -> Coord);
  380.         endline();
  381.         }
  382.  
  383.         if (IGGlblDrawPNormal && IP_HAS_PLANE_POLY(Pl)) {
  384.         bgnline();
  385.         for (i = 0; i < 3; i++)
  386.             PNormal[i] /= NumOfVertices;
  387.         v3d(PNormal);
  388.         for (i = 0; i < 3; i++)
  389.             PNormal[i] += Pl -> Plane[i] * IGGlblNormalLen;
  390.         v3d(PNormal);
  391.         endline();
  392.         }
  393.  
  394.         if (IGGlblDrawVNormal) {
  395.         for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
  396.             if (IP_HAS_NORMAL_VRTX(V)) {
  397.             for (j = 0; j < 3; j++)
  398.                 VNormal[j] = V -> Coord[j] +
  399.                          V -> Normal[j] * IGGlblNormalLen;
  400.             bgnline();
  401.             v3d(V ->Coord);
  402.             v3d(VNormal);
  403.             endline();
  404.             }
  405.         }
  406.         }
  407.     }
  408.     }
  409. }
  410.  
  411. /****************************************************************************
  412. * Draw a single Surface object using current modes and transformations.        *
  413. *   Surface must be with either E3 or P3 point type and must be NURB.        *
  414. *   Control points in SGI's format must be found in "_ctlpoints" attribute. *
  415. ****************************************************************************/
  416. void IGDrawSurface(IPObjectStruct *PObj)
  417. {
  418.     IPObjectStruct *PObjPolylines, *PObjCtlMesh, *PObjPolygons;
  419.     IPPolygonStruct *PPolylines, *PCtlMesh, *PPolygons, *PPolyTemp;
  420.  
  421.     if ((PObjPolylines = AttrGetObjectObjAttrib(PObj, "_isoline")) == NULL) {
  422.     CagdSrfStruct *Srf,
  423.         *Srfs = PObj -> U.Srfs;
  424.  
  425.     PObjPolylines = IPAllocObject("", IP_OBJ_POLY, NULL);
  426.     PObjPolylines -> Attrs = AttrCopyAttributes(PObj -> Attrs);
  427.     IP_SET_POLYLINE_OBJ(PObjPolylines);
  428.     for (Srf = Srfs; Srf != NULL; Srf = Srf -> Pnext) {
  429.         int NumOfIso[2];
  430.  
  431.         NumOfIso[0] = -IGGlblNumOfIsolines;
  432.         NumOfIso[1] = -IGGlblNumOfIsolines;
  433.         PPolylines = IritSurface2Polylines(Srf, NumOfIso,
  434.                            IGGlblSamplesPerCurve);
  435.  
  436.         for (PPolyTemp = PPolylines;
  437.          PPolyTemp -> Pnext;
  438.          PPolyTemp = PPolyTemp -> Pnext);
  439.         PPolyTemp -> Pnext = PObjPolylines -> U.Pl;
  440.         PObjPolylines -> U.Pl = PPolylines;
  441.     }
  442.     AttrSetObjectObjAttrib(PObj, "_isoline", PObjPolylines);
  443.     }
  444.  
  445.     if (IGGlblDrawSolid) {
  446.     if (IGGlblDrawSurfacePoly) {
  447.         if ((PObjPolygons = AttrGetObjectObjAttrib(PObj, "_polygons"))
  448.                                     == NULL) {
  449.         CagdSrfStruct *Srf,
  450.             *Srfs = PObj -> U.Srfs;
  451.  
  452.         PObjPolygons = IPAllocObject("", IP_OBJ_POLY, NULL);
  453.         PObjPolygons -> Attrs = AttrCopyAttributes(PObj -> Attrs);
  454.         IP_SET_POLYGON_OBJ(PObjPolygons);
  455.  
  456.         for (Srf = Srfs; Srf != NULL; Srf = Srf -> Pnext) {
  457.             PPolygons = IritSurface2Polygons(Srf, IGGlblFourPerFlat,
  458.                              1 << IGGlblFineNess, FALSE);
  459.  
  460.             if (PPolygons) {
  461.             for (PPolyTemp = PPolygons;
  462.                  PPolyTemp -> Pnext;
  463.                  PPolyTemp = PPolyTemp -> Pnext);
  464.             PPolyTemp -> Pnext = PObjPolygons -> U.Pl;
  465.             PObjPolygons -> U.Pl = PPolygons;
  466.             }
  467.         }
  468.         AttrSetObjectObjAttrib(PObj, "_polygons", PObjPolygons);
  469.         }
  470.  
  471.         IGDrawPolyNormal(PObjPolygons, TRUE);
  472.     }
  473.     else {
  474.         if ((PObjPolylines = AttrGetObjectObjAttrib(PObj, "_adap_iso"))
  475.                                     == NULL) {
  476.         CagdSrfStruct *Srf,
  477.             *Srfs = PObj -> U.Srfs;
  478.  
  479.         PObjPolylines = IPAllocObject("", IP_OBJ_POLY, NULL);
  480.         PObjPolylines -> Attrs = AttrCopyAttributes(PObj -> Attrs);
  481.         IP_SET_POLYLINE_OBJ(PObjPolylines);
  482.  
  483.         for (Srf = Srfs; Srf != NULL; Srf = Srf -> Pnext) {
  484.             PPolylines = IritSurface2AdapIso(Srf, IGGlblAdapIsoDir,
  485.                              GlblAdapIsoEps,
  486.                              IGGlblSamplesPerCurve);
  487.  
  488.             if (PPolylines) {
  489.             for (PPolyTemp = PPolylines;
  490.                  PPolyTemp -> Pnext;
  491.                  PPolyTemp = PPolyTemp -> Pnext);
  492.             PPolyTemp -> Pnext = PObjPolylines -> U.Pl;
  493.             PObjPolylines -> U.Pl = PPolylines;
  494.             }
  495.         }
  496.         AttrSetObjectObjAttrib(PObj, "_adap_iso", PObjPolylines);
  497.         }
  498.  
  499.         IGDrawPolyNormal(PObjPolylines, TRUE);
  500.     }
  501.     }
  502.     else
  503.         IGDrawPolyNormal(PObjPolylines, FALSE);
  504.  
  505.     if (IGGlblDrawSurfaceMesh) {
  506.     if ((PObjPolylines = AttrGetObjectObjAttrib(PObj, "_ctlmesh"))
  507.                                 == NULL) {
  508.         CagdSrfStruct *Srf,
  509.         *Srfs = PObj -> U.Srfs;
  510.  
  511.         PObjCtlMesh = IPAllocObject("", IP_OBJ_POLY, NULL);
  512.         PObjCtlMesh -> Attrs = AttrCopyAttributes(PObj -> Attrs);
  513.         IP_SET_POLYLINE_OBJ(PObjCtlMesh);
  514.         for (Srf = Srfs; Srf != NULL; Srf = Srf -> Pnext) {
  515.         PCtlMesh = IritSurface2CtlMesh(Srf);
  516.  
  517.         for (PPolyTemp = PCtlMesh;
  518.              PPolyTemp -> Pnext;
  519.              PPolyTemp = PPolyTemp -> Pnext);
  520.         PPolyTemp -> Pnext = PObjCtlMesh -> U.Pl;
  521.         PObjCtlMesh -> U.Pl = PCtlMesh;
  522.         }
  523.         AttrSetObjectObjAttrib(PObj, "_ctlmesh", PObjCtlMesh);
  524.     }
  525.  
  526.     IGDrawPolyNormal(AttrGetObjectObjAttrib(PObj, "_ctlmesh"), FALSE);
  527.     }
  528. }
  529.  
  530. /****************************************************************************
  531. * Create an adaptive isocurve coverage to a given surface.            *
  532. ****************************************************************************/
  533. static IPPolygonStruct *IritSurface2AdapIso(CagdSrfStruct *Srf,
  534.                         CagdSrfDirType Dir,
  535.                         RealType Eps, int SamplesPerCurve)
  536. {
  537.     CagdCrvStruct *Coverage, *OneCoverage, *Crv;
  538.     IPPolygonStruct
  539.     *IsoPoly = NULL;
  540.     CagdSrfStruct *NSrf;
  541.  
  542.     if (Dir == CAGD_NO_DIR)
  543.     Dir = Srf -> UOrder == 2 ? CAGD_CONST_U_DIR : CAGD_CONST_V_DIR;
  544.  
  545.     fprintf(stderr, "Generating adaptive isocurve coverage...\n");
  546.     if (GlblRuledSrfApprox) {
  547.     int IsBspline = TRUE;
  548.     CagdSrfStruct *RuledSrfs, *NormalSrf, *TSrf;
  549.  
  550.     if (CAGD_IS_BEZIER_SRF(Srf)) {
  551.         IsBspline = FALSE;
  552.         Srf = CnvrtBezier2BsplineSrf(Srf);
  553.     }
  554.     RuledSrfs = CagdPiecewiseRuledSrfApprox(Srf, TRUE, GlblRuledSrfEps,
  555.                         Dir);
  556.  
  557.     Coverage = NULL;
  558.     NormalSrf = CagdSrfNormalSrf(Srf);
  559.     for (TSrf = RuledSrfs; TSrf != NULL; TSrf = TSrf -> Pnext) {
  560.         CagdRType UMin, UMax, VMin, VMax;
  561.  
  562.         CagdSrfDomain(TSrf, &UMin, &UMax, &VMin, &VMax);
  563.         if (Dir == CAGD_CONST_V_DIR)
  564.         NSrf = CagdSrfRegionFromSrf(NormalSrf, UMin, UMax,
  565.                         CAGD_CONST_U_DIR);
  566.         else
  567.         NSrf = CagdSrfRegionFromSrf(NormalSrf, VMin, VMax,
  568.                         CAGD_CONST_V_DIR);
  569.         OneCoverage = CagdAdapIsoExtract(TSrf, NSrf, Dir,
  570.                          Eps, FALSE, FALSE);
  571.         CagdSrfFree(NSrf);
  572.  
  573.         for (Crv = OneCoverage; Crv -> Pnext != NULL; Crv = Crv -> Pnext);
  574.         Crv -> Pnext = Coverage;
  575.         Coverage = OneCoverage;
  576.         fprintf(stderr, "Done with one ruled surface approximation.\n");
  577.     }
  578.     CagdSrfFreeList(RuledSrfs);
  579.     CagdSrfFree(NormalSrf);
  580.     if (!IsBspline)
  581.         CagdSrfFree(Srf);
  582.  
  583.     /* Scan the adaptive isoline list. Note that normal curve is paired */
  584.     /* after Euclidean curve, so we can step two curves at a time.      */
  585.     for (Crv = Coverage; Crv != NULL; Crv = Crv -> Pnext -> Pnext) {
  586.         CagdCrvStruct
  587.         *NCrv = Crv -> Pnext;
  588.         IPPolygonStruct
  589.         *Poly = IritCurve2Polylines(Crv, 1);
  590.         RealType
  591.         *Nrml1 = Poly -> PVertex -> Normal,
  592.         *Nrml2 = Poly -> PVertex -> Pnext -> Normal;
  593.         CagdCoerceToE3(Nrml1, NCrv -> Points, 0, NCrv -> PType);
  594.         CagdCoerceToE3(Nrml2, NCrv -> Points, NCrv -> Length - 1,
  595.                NCrv -> PType);
  596.         PT_NORMALIZE(Nrml1);
  597.         PT_SCALE(Nrml1, -1.0);
  598.         PT_NORMALIZE(Nrml2);
  599.         PT_SCALE(Nrml2, -1.0);
  600.  
  601.         Poly -> Pnext = IsoPoly;
  602.         IsoPoly = Poly;
  603.     }
  604.     }
  605.     else {
  606.     NSrf = CagdSrfNormalSrf(Srf);
  607.  
  608.     Coverage = CagdAdapIsoExtract(Srf, NSrf, Dir, Eps, FALSE, FALSE);
  609.         fprintf(stderr,
  610.             "Done with adaptive isocurve surface approximation.\n");
  611.  
  612.     CagdSrfFree(NSrf);
  613.  
  614.     /* Scan the adaptive isoline list. Note that normal curve is paired */
  615.     /* after Euclidean curve, so we can step two curves at a time.      */
  616.     for (Crv = Coverage; Crv != NULL; Crv = Crv -> Pnext -> Pnext) {
  617.         IPVertexStruct *VP, *VN;
  618.         CagdCrvStruct
  619.         *NCrv = Crv -> Pnext;
  620.         IPPolygonStruct
  621.         *Poly = IritCurve2Polylines(Crv, IGGlblSamplesPerCurve),
  622.         *NPoly = IritCurve2Polylines(Crv -> Pnext, IGGlblSamplesPerCurve);
  623.  
  624.         for (VP = Poly -> PVertex, VN = NPoly -> PVertex;
  625.          VP != NULL;
  626.          VP = VP -> Pnext, VN = VN -> Pnext) {
  627.         PT_COPY(VP -> Normal, VN -> Coord);
  628.         PT_NORMALIZE(VP -> Normal);
  629.         PT_SCALE(VP -> Normal, -1.0);
  630.         }
  631.  
  632.         IPFreePolygonList(NPoly);
  633.  
  634.         Poly -> Pnext = IsoPoly;
  635.         IsoPoly = Poly;
  636.     }
  637.     }
  638.  
  639.     CagdCrvFreeList(Coverage);
  640.  
  641.     return IsoPoly;    
  642. }
  643.  
  644. /****************************************************************************
  645. * Routine to set the color according to the given object's color.        *
  646. ****************************************************************************/
  647. void IGSetColorObj(IPObjectStruct *PObj)
  648. {
  649.     int c, Color[3];
  650.  
  651.     if (AttrGetObjectRGBColor(PObj, &Color[0], &Color[1], &Color[2])) {
  652.     SetColorRGB(Color);
  653.     }
  654.     else if ((c = AttrGetObjectColor(PObj)) != IP_ATTR_NO_COLOR) {
  655.     SetColorIndex(c);
  656.     }
  657.     else {
  658.     /* Use white as default color: */
  659.     SetColorIndex(IG_IRIT_WHITE);
  660.     }
  661. }
  662.  
  663. /****************************************************************************
  664. * Routine to set the color according to the given color index.            *
  665. ****************************************************************************/
  666. static void SetColorIndex(int c)
  667. {
  668.     int Color[3];
  669.  
  670.     if (c < 0 || c > IG_MAX_COLOR)
  671.         c = IG_IRIT_WHITE;
  672.  
  673.     Color[0] = Colors[c][0];
  674.     Color[1] = Colors[c][1];
  675.     Color[2] = Colors[c][2];
  676.  
  677.     SetColorRGB(Color);
  678. }
  679.  
  680. /****************************************************************************
  681. * Routine to set the color according to the given RGB values.            *
  682. ****************************************************************************/
  683. static void SetColorRGB(int Color[3])
  684. {
  685.     int i;
  686.     static float
  687.     Ambient = 0.25,
  688.     Diffuse = 0.75,
  689.     Specular = 1.0;
  690.     static float
  691.     Material[] = {
  692.         AMBIENT,  0.25, 0.25, 0.25,
  693.         DIFFUSE,  0.75, 0.75, 0.75,
  694.         SPECULAR, 1.00, 1.00, 1.00,
  695.         SHININESS, 50,
  696.         LMNULL
  697.     };
  698.  
  699.     c3i((long *) Color);
  700.     if (IGGlblDepthCue)
  701.     lRGBrange(0, 0, 0, Color[0], Color[1], Color[2], 0x0, 0x7fffff);
  702.  
  703.     /* Prepare material structure in this color and select it. */
  704.     for (i = 0; i < 3; i++) {
  705.     Material[1 + i] = Ambient * Color[i] / 255.0;
  706.     Material[5 + i] = Diffuse * Color[i] / 255.0;
  707.     Material[9 + i] = Specular * Color[i] / 255.0;
  708.     }
  709.     lmdef(DEFMATERIAL, 1, sizeof(Material) / sizeof(float), Material);
  710. }
  711.  
  712. /*****************************************************************************
  713. * Set up and draw a transformation window.                     *
  714. *****************************************************************************/
  715. static void SetTransformWindow(void)
  716. {
  717.     long PrefPos[4];
  718.  
  719. #ifndef _AIX
  720.     foreground();
  721. #endif
  722.  
  723.     if (sscanf(IGGlblTransPrefPos, "%ld, %ld, %ld, %ld",
  724.            &PrefPos[0], &PrefPos[1], &PrefPos[2], &PrefPos[3]) == 4)
  725.     prefposition(PrefPos[0], PrefPos[1], PrefPos[2], PrefPos[3]);
  726.     else if (sscanf(IGGlblTransPrefPos, "%ld, %ld",
  727.             &PrefPos[0], &PrefPos[1]) == 2)
  728.     prefsize(PrefPos[0], PrefPos[1]);
  729.     winopen("Poly3dTrans");
  730.     winconstraints();
  731.     wintitle("xGLdrvs");
  732.     RGBmode();
  733.     gconfig();
  734.     getorigin(&TransWinLeft, &TransWinLow);
  735.     getsize(&TransWinWidth, &TransWinHeight);
  736.     TransWinWidth2 = TransWinWidth / 2;
  737.     TransWinID = winget();
  738.  
  739.     SetColorRGB(IGGlblBackGroundColor);
  740.     clear();
  741.  
  742.     /* This is wierd. without the sleep the gl get mixed up between the two  */
  743.     /* windows. If you have any idea why, let me know...             */
  744.     sleep(1);
  745. }
  746.  
  747. /*****************************************************************************
  748. * Set up and draw a transformation window.                     *
  749. *****************************************************************************/
  750. static void RedrawTransformWindow(void)
  751. {
  752.     int i;
  753.     long SubTransPosX, SubTransPosY, SubTransWidth, SubTransHeight;
  754.  
  755.     /* Make sure the menu is consistent with internatal data. */
  756.     InteractMenu.SubWindows[0].Str =
  757.     IGGlblTransformMode == IG_TRANS_OBJECT ? "Object Coords."
  758.                          : "Screen Coords.";
  759.     InteractMenu.SubWindows[1].Str =
  760.     IGGlblViewMode == IG_VIEW_PERSPECTIVE ? "Perspective" : "Orthographic";
  761.  
  762.     winset(TransWinID);                /* Draw in the transformation window. */
  763.  
  764.     SubTransWidth = (int) (TransWinWidth * INTERACT_SUB_WINDOW_WIDTH);
  765.     SubTransHeight = (int) (TransWinHeight * INTERACT_SUB_WINDOW_HEIGHT);
  766.     SubTransPosX = (TransWinWidth - SubTransWidth) / 2;
  767.  
  768.     SetColorRGB(IGGlblBackGroundColor);
  769.     clear();
  770.  
  771.     for (i = 0; i < INTERACT_NUM_OF_SUB_WNDWS; i++) {
  772.     SetColorIndex(InteractMenu.SubWindows[i].Color);
  773.     SubTransPosY = (int) (TransWinHeight * InteractMenu.SubWindows[i].Y);
  774.  
  775.     move2i(SubTransPosX, SubTransPosY);
  776.     draw2i(SubTransPosX + SubTransWidth, SubTransPosY);
  777.     draw2i(SubTransPosX + SubTransWidth, SubTransPosY + SubTransHeight);
  778.     draw2i(SubTransPosX, SubTransPosY + SubTransHeight);
  779.     draw2i(SubTransPosX, SubTransPosY);
  780.     if (InteractMenu.SubWindows[i].TextInside) {
  781.         DrawText(InteractMenu.SubWindows[i].Str,
  782.              TransWinWidth / 2,
  783.              SubTransPosY + SubTransHeight / 2);
  784.     }
  785.     else {
  786.         DrawText(InteractMenu.SubWindows[i].Str,
  787.              (TransWinWidth - SubTransWidth) / 3,
  788.              SubTransPosY + SubTransHeight / 2);
  789.         move2i(SubTransPosX + SubTransWidth / 2, SubTransPosY);
  790.         draw2i(SubTransPosX + SubTransWidth / 2,
  791.            SubTransPosY + SubTransHeight);
  792.     }
  793.     }
  794.  
  795.     for (i = 0; i < INTERACT_NUM_OF_STRINGS; i++) {
  796.     SetColorIndex(InteractMenu.Strings[i].Color);
  797.     DrawText(InteractMenu.Strings[i].Str,
  798.          (int) (InteractMenu.Strings[i].X * TransWinWidth),
  799.          (int) (InteractMenu.Strings[i].Y * TransWinHeight));
  800.     }
  801.  
  802.     winset(ViewWinID);             /* Go back to the default drawing window. */
  803. }
  804.  
  805. /*****************************************************************************
  806. *   Routine to clear the viewing area.                         *
  807. *****************************************************************************/
  808. static void ClearViewArea(void)
  809. {
  810.     SetColorRGB(IGGlblBackGroundColor);
  811.     clear();
  812.     mmode(MVIEWING);
  813.     shademodel(GOURAUD);
  814.     linewidth(IGGlblLineWidth);
  815.  
  816.     if (APX_EQ(IGGlblZMinClip, IGGlblZMaxClip))
  817.         IGGlblZMaxClip += EPSILON;
  818.     ortho(-1.0, 1.0, -1.0, 1.0, IGGlblZMinClip, IGGlblZMaxClip);
  819.  
  820.     if (winget() == ViewWinID) {
  821.     /* activate zbuffer only if we are in solid drawing mode. */
  822.     if (IGGlblDrawSolid) {
  823.         /* Define necessary staff for Lighting. */
  824.         lmbind(MATERIAL, 1);
  825.         lmbind(LMODEL, 1);
  826.         lmbind(LIGHT1, 1);
  827.         lmbind(LIGHT2, 2);
  828.  
  829.         zbuffer(TRUE);
  830.         zclear();
  831.     }
  832.     else {
  833.         zbuffer(FALSE);
  834.     }
  835.     }
  836. }
  837.  
  838. /*****************************************************************************
  839. * Set up and draw a view window.                             *
  840. *****************************************************************************/
  841. static void SetViewWindow(void)
  842. {
  843.     long PrefPos[4];
  844.     static float Light1[] = {
  845.     AMBIENT, 0.25, 0.25, 0.25,
  846.     POSITION, 0.1, 0.5, 1.0, 0.0,
  847.     LMNULL
  848.     };
  849.     static float Light2[] = {
  850.     AMBIENT, 0.25, 0.25, 0.25,
  851.     POSITION, 0.5, -1.5, -1.0, 0.0,
  852.     LMNULL
  853.     };
  854.  
  855. #ifndef _AIX
  856.     foreground();
  857. #endif
  858.  
  859.     if (sscanf(IGGlblViewPrefPos, "%ld, %ld, %ld, %ld",
  860.            &PrefPos[0], &PrefPos[1], &PrefPos[2], &PrefPos[3]) == 4)
  861.     prefposition(PrefPos[0], PrefPos[1], PrefPos[2], PrefPos[3]);
  862.     else if (sscanf(IGGlblViewPrefPos, "%ld, %ld",
  863.             &PrefPos[0], &PrefPos[1]) == 2)
  864.     prefsize(PrefPos[0], PrefPos[1]);
  865.     winopen("Poly3dView");
  866.     winconstraints();
  867.     wintitle("xGLdrvs");
  868.     if (IGGlblDoDoubleBuffer)
  869.     doublebuffer();
  870.     else
  871.         singlebuffer();
  872.     RGBmode();
  873.     if (IGGlblDepthCue) {
  874. #    ifndef _AIX
  875.         glcompat(GLC_ZRANGEMAP, 1);
  876. #    endif /* _AIX */
  877.     lRGBrange(0, 0, 0, 255, 255, 255, 0x0, 0x7fffff);
  878.     depthcue(IGGlblDepthCue);
  879.     }
  880.     else
  881.         depthcue(FALSE);
  882.     if (IGGlblAntiAliasing) {
  883. #    ifndef _AIX
  884.         if (getgdesc(GD_PNTSMOOTH_CMODE) == 0 ||
  885.         getgdesc(GD_BITS_NORM_DBL_CMODE) < 8)
  886.         IGGlblAntiAliasing = FALSE;
  887.         else {
  888.         subpixel(TRUE);
  889.         pntsmooth(SMP_ON);
  890.         }
  891. #    endif /* _AIX */
  892.     }
  893.     gconfig();
  894.     getorigin(&ViewWinLeft, &ViewWinLow);
  895.     getsize(&ViewWinWidth, &ViewWinHeight);
  896.     ViewWinWidth2 = ViewWinWidth / 2;
  897.     ViewWinHeight2 = ViewWinHeight / 2;
  898.     
  899.     ViewWinID = winget();
  900.  
  901.     concave(TRUE);
  902.  
  903.     /* Define necessary staff for Lighting. */
  904.     lmdef(DEFMATERIAL, 1, 0, NULL);
  905.     lmdef(DEFLMODEL, 1, 0, NULL);
  906.     lmdef(DEFLIGHT, 1, sizeof(Light1) / sizeof(float), Light1);
  907.     lmdef(DEFLIGHT, 2, sizeof(Light2) / sizeof(float), Light2);
  908.  
  909.     ClearViewArea();
  910.     if (IGGlblDoDoubleBuffer)
  911.     swapbuffers();
  912.  
  913.     /* This is wierd. without the sleep the gl get mixed up between the two  */
  914.     /* windows. If you have any idea why, let me know...             */
  915.     sleep(1);
  916. }
  917.  
  918. /*****************************************************************************
  919. * Set up and draw a viewing window.                         *
  920. *****************************************************************************/
  921. static void RedrawViewWindow(void)
  922. {
  923.     IPObjectStruct *PObj;
  924.     Matrix CrntView;
  925.     int i, j, k;
  926.  
  927.     ClearViewArea();
  928.  
  929.     if (IGGlblViewMode == IG_VIEW_PERSPECTIVE) {
  930.     for (i = 0; i < 4; i++)
  931.         for (j = 0; j < 4; j++) {
  932.         CrntView[i][j] = 0;
  933.         for (k = 0; k < 4; k++)
  934.             CrntView[i][j] += IritPrsrViewMat[i][k] *
  935.                       IritPrsrPrspMat[k][j];
  936.         }
  937.     }
  938.     else {
  939.     for (i = 0; i < 4; i++)
  940.         for (j = 0; j < 4; j++)
  941.         CrntView[i][j] = IritPrsrViewMat[i][j];
  942.     }
  943.     loadmatrix(CrntView);
  944.  
  945.     for (PObj = IGGlblDisplayList; PObj != NULL; PObj = PObj -> Pnext)
  946.     IGDrawObject(PObj);
  947.  
  948.     if (IGGlblDoDoubleBuffer)
  949.     swapbuffers();
  950. }
  951.  
  952. /******************************************************************************
  953. * Handle gl events                                  *
  954. ******************************************************************************/
  955. static IGGraphicEventType GetGraphicEvent(RealType *ChangeFactor)
  956. {
  957.     static IGGraphicEventType
  958.     LastEvent = IG_EVENT_NONE;
  959.     static long
  960.     LastX = -1;
  961.     int i, TransformRequest,
  962.         LeftButtonIsPressed = getbutton(LEFTMOUSE) == 1;
  963.     IGGraphicEventType
  964.     RetVal = IG_EVENT_NONE;
  965.     short data;
  966.     long x, y, dev;
  967.     RealType XPos, YPos;
  968.  
  969.     /* Allow continuous drag on following events only: */
  970.     if (LeftButtonIsPressed && !IG_IS_DRAG_EVENT(LastEvent)) {
  971.     while (getbutton(LEFTMOUSE) == 1);
  972.     LeftButtonIsPressed = FALSE;
  973.     }
  974.  
  975.     if (LeftButtonIsPressed) {
  976.     /* Allow leaving the Trans window if still pressed, and use last     */
  977.     /* event as the returned event.    Note we wait until current position  */
  978.     /* is different from last one to make sure we do something.          */
  979.     while((x = getvaluator(MOUSEX) - TransWinLeft) == LastX &&
  980.           getbutton(LEFTMOUSE) == 1);
  981.     if (x != LastX) {
  982.         *ChangeFactor = (((RealType) x) - LastX) / TransWinWidth2;
  983.         LastX = x;
  984.         return LastEvent;
  985.     }
  986.     else
  987.         LeftButtonIsPressed = FALSE;
  988.     }
  989.  
  990.     LastEvent = IG_EVENT_NONE;
  991.  
  992.     while (RetVal == IG_EVENT_NONE) {
  993.     /* Wait for left button to be pressed in the Trans window. Note this */
  994.     /* is the loop we are going to cycle in idle time.             */
  995.     for (TransformRequest = FALSE; !TransformRequest;) {
  996.         x = getvaluator(MOUSEX);
  997.         y = getvaluator(MOUSEY);
  998.  
  999.         if (qtest()) {                  /* Any external event occured? */
  1000.         switch (dev = qread(&data)) {
  1001.             case REDRAW:
  1002.             if (data == ViewWinID) {
  1003.                 getorigin(&ViewWinLeft, &ViewWinLow);
  1004.                 getsize(&ViewWinWidth, &ViewWinHeight);
  1005.                 ViewWinWidth2 = ViewWinWidth / 2;
  1006.                 ViewWinHeight2 = ViewWinHeight / 2;
  1007.                 reshapeviewport();
  1008.                 ortho2(-0.5, ViewWinWidth - 0.5,
  1009.                    -0.5, ViewWinHeight - 0.5);
  1010.                 RedrawViewWindow();
  1011.             }
  1012.             else if (data == TransWinID) {
  1013.                 winset(TransWinID);
  1014.                 getorigin(&TransWinLeft, &TransWinLow);
  1015.                 getsize(&TransWinWidth, &TransWinHeight);
  1016.                 reshapeviewport();
  1017.                 ortho2(-0.5, TransWinWidth - 0.5,
  1018.                    -0.5, TransWinHeight - 0.5);
  1019.                 TransWinWidth2 = TransWinWidth / 2;
  1020.                 RedrawTransformWindow();
  1021.                 winset(ViewWinID);
  1022.             }
  1023.             break;
  1024.             case RIGHTMOUSE:
  1025.             if (data &&
  1026.                 IGHandleState(dopup(GlblStateMenu), FALSE)) {
  1027.                 *ChangeFactor = 0.0;
  1028.                 return IG_EVENT_STATE;
  1029.             }
  1030.             break;
  1031.             case LEFTMOUSE:
  1032.             TransformRequest = data;
  1033.             break;
  1034.         }
  1035.         continue;
  1036.         }
  1037.  
  1038.         /* Maybe we have something in communication socket. */
  1039.         if (!IGGlblStandAlone &&
  1040.         IGReadObjectsFromSocket(IGGlblViewMode, &IGGlblDisplayList))
  1041.         RedrawViewWindow();
  1042.  
  1043.         IritSleep(10);           /* So we do not use all CPU on idle. */
  1044.     }
  1045.  
  1046.     x -= TransWinLeft;
  1047.     y -= TransWinLow;
  1048.  
  1049.     XPos = ((RealType) x) / TransWinWidth;
  1050.     YPos = ((RealType) y) / TransWinHeight;
  1051.  
  1052.     /* Make sure we are in bound in the X direction. */
  1053.     if (XPos < (1.0 - INTERACT_SUB_WINDOW_WIDTH) / 2.0 ||
  1054.         XPos > 1.0 - (1.0 - INTERACT_SUB_WINDOW_WIDTH) / 2.0)
  1055.         continue;
  1056.  
  1057.     /* Now search the sub window the event occured in. */
  1058.     for (i = 0; i < INTERACT_NUM_OF_SUB_WNDWS; i++) {
  1059.         if (InteractMenu.SubWindows[i].Y <= YPos &&
  1060.         InteractMenu.SubWindows[i].Y + INTERACT_SUB_WINDOW_HEIGHT >=
  1061.                                     YPos) {
  1062.         RetVal = InteractMenu.SubWindows[i].Event;
  1063.         break;
  1064.         }
  1065.     }
  1066.     if (i == INTERACT_NUM_OF_SUB_WNDWS)
  1067.         continue;
  1068.  
  1069.     /* Take care of special cases in which the window should be updated. */
  1070.     switch (RetVal) {
  1071.         case IG_EVENT_SCR_OBJ_TGL:
  1072.         IGGlblTransformMode = IGGlblTransformMode == IG_TRANS_OBJECT ?
  1073.                                  IG_TRANS_SCREEN :
  1074.                                  IG_TRANS_OBJECT;
  1075.         RedrawTransformWindow();
  1076.         break;
  1077.         case IG_EVENT_PERS_ORTHO_TGL:
  1078.             IGGlblViewMode = IGGlblViewMode == IG_VIEW_PERSPECTIVE ?
  1079.                            IG_VIEW_ORTHOGRAPHIC :
  1080.                            IG_VIEW_PERSPECTIVE;
  1081.         RedrawTransformWindow();
  1082.         break;
  1083.         case IG_EVENT_QUIT:
  1084.         break;
  1085.     }
  1086.  
  1087.     *ChangeFactor = (((RealType) x) - TransWinWidth2) / TransWinWidth2;
  1088.     }
  1089.  
  1090.     LastEvent = RetVal;
  1091.     LastX = x;
  1092.  
  1093.     return RetVal;
  1094. }
  1095. /******************************************************************************
  1096. * Handle the event of a pop up window.                          *
  1097. ******************************************************************************/
  1098. int IGHandleState(int State, int Refresh)
  1099. {
  1100.     int UpdateView = TRUE;
  1101.  
  1102.     switch (State) {
  1103.     case IG_STATE_SCR_OBJ_TGL:
  1104.         IGGlblTransformMode = IGGlblTransformMode == IG_TRANS_OBJECT ?
  1105.                              IG_TRANS_SCREEN :
  1106.                              IG_TRANS_OBJECT;
  1107.         RedrawTransformWindow();
  1108.         UpdateView = FALSE;
  1109.         break;
  1110.     case IG_STATE_PERS_ORTHO_TGL:
  1111.         IGGlblViewMode = IGGlblViewMode == IG_VIEW_PERSPECTIVE ?
  1112.                            IG_VIEW_ORTHOGRAPHIC :
  1113.                            IG_VIEW_PERSPECTIVE;
  1114.         RedrawTransformWindow();
  1115.         break;
  1116.     case IG_STATE_DRAW_SOLID:
  1117.         IGGlblDrawSolid = !IGGlblDrawSolid;
  1118.         /* And fall thru to disable the depth cueing. */
  1119.         IGGlblDepthCue = TRUE; 
  1120.     case IG_STATE_DEPTH_CUE:
  1121.         IGGlblDepthCue = !IGGlblDepthCue;
  1122.         if (IGGlblDepthCue) {
  1123. #            ifndef _AIX
  1124.             glcompat(GLC_ZRANGEMAP, 1);
  1125. #            endif /* _AIX */
  1126.         lRGBrange(0, 0, 0, 255, 255, 255,
  1127.               0x0, 0x7fffff);
  1128.         depthcue(IGGlblDepthCue);
  1129.         }
  1130.         else
  1131.         depthcue(FALSE);
  1132.         break;
  1133.     case IG_STATE_DOUBLE_BUFFER:
  1134.         IGGlblDoDoubleBuffer = !IGGlblDoDoubleBuffer;
  1135.         winset(ViewWinID);
  1136.         if (IGGlblDoDoubleBuffer)
  1137.         doublebuffer();
  1138.         else
  1139.         singlebuffer();
  1140.         gconfig();
  1141.         break;
  1142.     case IG_STATE_ANTI_ALIASING:
  1143.         IGGlblAntiAliasing = !IGGlblAntiAliasing;
  1144. #        ifndef _AIX
  1145.         if (getgdesc(GD_PNTSMOOTH_CMODE) == 0 ||
  1146.             getgdesc(GD_BITS_NORM_DBL_CMODE) < 8)
  1147.             IGGlblAntiAliasing = FALSE;
  1148.         else
  1149.             subpixel(IGGlblAntiAliasing);
  1150. #        endif /* _AIX */
  1151.         break;
  1152.     case IG_STATE_FINER_APPROX:
  1153.         IGGlblSamplesPerCurve++;
  1154.         IGGlblFineNess++;
  1155.         IGActiveListFreeNamedAttribute("_polygons");
  1156.         IGActiveListFreeNamedAttribute("_adap_iso");
  1157.         IGActiveListFreeNamedAttribute("_isoline");
  1158.         break;
  1159.     case IG_STATE_COARSER_APPROX:
  1160.         IGGlblFineNess--;
  1161.         if (IGGlblFineNess < 2)
  1162.         IGGlblFineNess = 2;
  1163.         IGGlblSamplesPerCurve--;
  1164.         if (IGGlblSamplesPerCurve < 2)
  1165.         IGGlblSamplesPerCurve = 2;
  1166.         IGActiveListFreeNamedAttribute("_polygons");
  1167.         IGActiveListFreeNamedAttribute("_adap_iso");
  1168.         IGActiveListFreeNamedAttribute("_isoline");
  1169.         break;
  1170.     case IG_STATE_WIDER_LINES:
  1171.         IGGlblLineWidth *= 2;
  1172.         linewidth(IGGlblLineWidth);
  1173.         break;
  1174.     case IG_STATE_NARROW_LINES:
  1175.         IGGlblLineWidth /= 2;
  1176.         if (IGGlblLineWidth < 1)
  1177.         IGGlblLineWidth = 1;
  1178.         linewidth(IGGlblLineWidth);
  1179.         break;
  1180.     case IG_STATE_FINER_ADAP_ISO:
  1181.         GlblAdapIsoEps /= 2.0;
  1182.         IGActiveListFreeNamedAttribute("_adap_iso");
  1183.         break;
  1184.     case IG_STATE_COARSER_ADAP_ISO:
  1185.         GlblAdapIsoEps *= 2.0;
  1186.         IGActiveListFreeNamedAttribute("_adap_iso");
  1187.         break;
  1188.     case IG_STATE_FINER_RULED_SRF:
  1189.         GlblRuledSrfEps /= 2.0;
  1190.         IGActiveListFreeNamedAttribute("_adap_iso");
  1191.         break;
  1192.     case IG_STATE_COARSER_RULED_SRF:
  1193.         GlblRuledSrfEps *= 2.0;
  1194.         IGActiveListFreeNamedAttribute("_adap_iso");
  1195.         break;
  1196.     case IG_STATE_RULED_SRF_APPROX:
  1197.         GlblRuledSrfApprox = !GlblRuledSrfApprox;
  1198.         IGActiveListFreeNamedAttribute("_adap_iso");
  1199.         break;
  1200.     case IG_STATE_ADAP_ISO_DIR:
  1201.         if (IGGlblAdapIsoDir == CAGD_CONST_U_DIR)
  1202.         IGGlblAdapIsoDir = CAGD_CONST_V_DIR;
  1203.         else
  1204.         IGGlblAdapIsoDir = CAGD_CONST_U_DIR;
  1205.         IGActiveListFreeNamedAttribute("_adap_iso");
  1206.         break;
  1207.     default:
  1208.         UpdateView = IGDefaultStateHandler(State, Refresh);
  1209.     }
  1210.  
  1211.     if (Refresh && UpdateView)
  1212.     RedrawViewWindow();
  1213.  
  1214.     IGCreateStateMenu();
  1215.  
  1216.     return UpdateView;
  1217. }
  1218.  
  1219. /******************************************************************************
  1220. * Draw text centered at the given position.                      *
  1221. ******************************************************************************/
  1222. static void DrawText(char *Str, long PosX, long PosY)
  1223. {
  1224.     long Width = strwidth(Str);
  1225.  
  1226.     cmov2s(PosX - Width / 2, PosY - (getheight() / 2 - getdescender()));
  1227.     charstr(Str);
  1228. }
  1229.  
  1230. /****************************************************************************
  1231. * Make noise function.                                *
  1232. ****************************************************************************/
  1233. void IGIritBeep(void)
  1234. {
  1235.     ringbell();
  1236. }
  1237.